package net.test.piggy.controller;

import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.UpdateAliasesRequest;
import co.elastic.clients.elasticsearch.indices.update_aliases.AddAction;
import net.test.piggy.model.po.TestPO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@Controller
@RequestMapping("/test")
public class ElasticController {

    Logger logger = LoggerFactory.getLogger(ElasticController.class);
    @Resource
    private ElasticsearchClient elasticsearchClient;
    @Resource
    private ElasticsearchAsyncClient elasticsearchAsyncClient;

    @ResponseBody
    @GetMapping("/test01")
    public String test01() {
        return "@test01";
    }

    @ResponseBody
    @GetMapping("/001")
    public String fun001() throws IOException {
        CreateIndexResponse createIndexResponse = elasticsearchClient.indices().create(
                c -> c.index("my-index-000008"));
        System.out.println(createIndexResponse.acknowledged());
        return "@fun001";
    }

    @ResponseBody
    @GetMapping("/002")
    public String fun002() throws IOException {
        if (elasticsearchClient.exists(
                b -> b.index("my-index-000001").id("bTWPj4wBeGohIJG6mGgV")).value()
        ) {
            logger.info("product exists");
        }
        return "@fun002";
    }

    @ResponseBody
    @GetMapping("/003")
    public String fun003() {
        elasticsearchAsyncClient.exists(b -> b.index("my-index-000001").id("bTWPj4wBeGohIJG6mGgV"))
                .whenComplete((response, exception) -> {
                    try {
                        Thread.sleep(3000);
                        if (exception != null) {
                            logger.error("Failed to index", exception);
                        } else {
                            logger.info("Product exists");
                        }
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
        return "@fun003";
    }

    @ResponseBody
    @GetMapping("/004")
    public String fun004() throws IOException {
        AddAction addAction = new AddAction.Builder().index("my-index-000007")
                .alias("piggy-index").build();
        UpdateAliasesRequest build = new UpdateAliasesRequest.Builder()
                .actions(a -> a.add(addAction)).build();
        boolean acknowledged = elasticsearchClient.indices()
                .updateAliases(build).acknowledged();
        logger.info(" --> " + acknowledged);
        return "@fun004";
    }


    @ResponseBody
    @GetMapping("/005")
    public String fun005() throws IOException {
        TestPO testPO = new TestPO();
        testPO.setAge(20);
        testPO.setName("admin");
        // 1 添加
        IndexRequest.Builder<Object> document = new IndexRequest.Builder<>()
                .index("my-index-000001")
                .document(testPO);

        IndexRequest<Object> build = document.build();
        IndexResponse index = elasticsearchClient.index(build);

        // 2 id不存在添加 id存在全量修改
        IndexResponse indexResponse = elasticsearchClient.index(b -> b
                .index("my-index-000001").id("oe2flIwBTh5XsTOYghak")
                .document(testPO));
        return "@fun005";
    }


    @ResponseBody
    @GetMapping("/006")
    public String fun006() throws IOException {
        TestPO testPO = new TestPO();
        testPO.setEmail("piggy@126.com");
        UpdateResponse<TestPO> update = elasticsearchClient.update(
                param -> param.index("my-index-000001").id("7").doc(testPO), TestPO.class);
        return "@fun006";
    }

    @ResponseBody
    @GetMapping("/007")
    public String fun007() throws IOException {
        DeleteResponse delete = elasticsearchClient.delete(
                a -> a.index("my-index-000001").id("oe2flIwBTh5XsTOYghak"));
        return "@fun007";
    }

    @ResponseBody
    @GetMapping("/008")
    public List<TestPO> fun008() throws IOException {
        SearchResponse<TestPO> search = elasticsearchClient.search(s -> s.index("my-index-000001")
                .query(q -> q.match(m -> m.field("manager.name.last").query("猪"))), TestPO.class);
        List<Hit<TestPO>> hits = search.hits().hits();
        List<TestPO> list = new ArrayList<>();
        for(Hit<TestPO> hit :hits){
            TestPO source = hit.source();
            list.add(source);
        }
        return list;
    }

    @ResponseBody
    @GetMapping("/009")
    public String fun009() throws IOException {
        SearchResponse<TestPO> search = elasticsearchClient.search(s -> s.index("my-index-000001")
                .query(q -> q.term(t->t.field("manager.name.last").value("猪")))
                .sort(sort->sort.field(f->f.field("age").order(SortOrder.Desc)
                        .field("create_date").order(SortOrder.Desc))), TestPO.class);
        List<Hit<TestPO>> hits = search.hits().hits();
        for(Hit<TestPO> hit :hits){
            TestPO source = hit.source();
            System.out.println(source);
        }
        return "@fun009";
    }
}
